var canvas = {
	'width' : 800,
	'height' : 600,
	'ctx' : document.getElementById('canvas').getContext('2d')
};

var sprites = {
	heroWalk : {
		src : 'img/hero.png',
		direction : 0,
		numberOfFrames : 8,
		finite: false
	},
	heroHit : {
		src : 'img/hit.png',
		direction : 0,
		numberOfFrames : 5,
		finite: true
	},
	heroSpell : {
		src : 'img/spell.png',
		direction : 0,
		numberOfFrames : 5,
		finite: true
	},
	fireball : {
		src : 'img/fireball.png',
		direction : 0,
		numberOfFrames : 7,
		finite: false
	},
	shieldWalk :{
		src : 'img/shield_walk.png',
		direction : 0,
		numberOfFrames : 8,
		finite: false	
	},
	shieldHit :{
		src : 'img/shield_hit.png',
		direction : 0,
		numberOfFrames : 5,
		finite: false	
	},
	shieldSpell :{
		src : 'img/empty.png',
		direction : 0,
		numberOfFrames : 5,
		finite: false	
	},
	map00 :{
		src : 'img/map0.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map01 :{
		src : 'img/map1.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map02 :{
		src : 'img/map2.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map10 :{
		src : 'img/map3.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map11 :{
		src : 'img/map4.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map12 :{
		src : 'img/map5.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	map12 :{
		src : 'img/minimap.png',
		direction : 0,
		numberOfFrames : 0,
		finite: false	
	},
	monster1Walk : {
		src : 'img/monster1walk.png',
		direction : 0,
		numberOfFrames : 8,
		finite: false
	},
	monster1Hit : {
		src : 'img/monster1hit.png',
		direction : 0,
		numberOfFrames : 5,
		finite: false
	}
};
var keysDown = {};
var loadedImages = 0;
var loadingInt;

function loadSpride (sprite){
	sprite.image = new Image();
	sprite.image.src = sprite.src;
	sprite.image.onload = function(){
		loadedImages++;
		sprite.isLoad = true;
	}
}

function loading(){
	if (loadedImages < 2){
		console.log('loading');	
	}else{
		clearInterval(loadingInt);
		main();	
	}
}

(function (){
	for (key in sprites){
		loadSpride(sprites[key])
	}
	loadingInt = setInterval(loading, 80);
})();

var hero = {
	x: 500,
	y: 10,
	w: 64,
	h: 64,
	direction: 3,							//0 up, 1 left, 2 down, 3 right
	frame: 0,
	speed: 5,
	action: 'heroWalk',
	isMoving: false,
	casts: {},
	armor: {shield: new Armor('shieldWalk')},
	numOfCasts: 0,
	draw: function(){
		//context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
		canvas.ctx.drawImage(sprites[hero.action].image, 0+Math.floor(hero.frame)*hero.w, 0+hero.direction*hero.h, hero.w, hero.h, hero.x, hero.y, hero.w, hero.h);
		for(key in hero.armor){
			canvas.ctx.drawImage(sprites[hero.armor[key].sprite].image, 0+Math.floor(hero.frame)*hero.w, 0+hero.direction*hero.h, hero.w, hero.h, hero.x, hero.y, hero.w, hero.h);
			//console.log(sprites[hero.armor[key].sprite].image)
		}
	},
	updateFrame: function(){
		if(hero.frame >= sprites[hero.action].numberOfFrames){
			hero.action = 'heroWalk';
			hero.armor.shield.sprite = 'shieldWalk'
			hero.frame = 0;
		}else{
			hero.frame += hero.speed/10;
		}
	},
	checkForMonster : function () {
		if(Math.abs(hero.x-monster.x)<32 && Math.abs(hero.y-monster.y)<32) {
			return true;
		}
		return false;
	},
	update: function(){
		hero.isMoving = false;
		if (sprites[hero.action].finite){     //if the action is finite (spell or hit), we only update its frames until it is done (the finite action).
			hero.updateFrame();
			return;
		}
		if(map.isChanging){
			return;
		}
		if (32 in keysDown) { //Player holding space				
			hero.action = 'heroHit';
			hero.armor.shield.sprite = 'shieldHit'
			hero.frame = 0;
			hero.updateFrame();
			return;
			
		}
		
		if (16 in keysDown) { //Player holding shift		
			hero.action = 'heroSpell';
			hero.armor.shield.sprite = 'shieldSpell'
			hero.frame = 0;
			hero.updateFrame();
			setTimeout(function (){
				hero.casts[hero.numOfCasts] = (new Fireball(hero.x + 11, hero.y + 20, hero.direction, hero.numOfCasts++));
			}, 300);
			return;
			
		}
		
		if (38 in keysDown) { // Player holding up
			hero.direction = 0;
			if (!map.isClear(hero.x, hero.y, hero.direction)){
				return;
			}
			hero.y -= hero.speed;
			hero.isMoving = true;
		}
		if (40 in keysDown) { // Player holding down
			hero.direction = 2;
			if (!map.isClear(hero.x, hero.y, hero.direction)){
				return;
			}
			hero.y += hero.speed;
			hero.isMoving = true;
		}
		if (37 in keysDown) { // Player holding left
			hero.direction = 1;
			if (!map.isClear(hero.x, hero.y, hero.direction)){
				return;
			}
			hero.x -= hero.speed;
			hero.isMoving = true;
		}
		if (39 in keysDown) { // Player holding right
			hero.direction = 3;
			if (!map.isClear(hero.x, hero.y, hero.direction)){
				return;
			}
			hero.x += hero.speed;
			hero.isMoving = true;
		}
		
		if(hero.isMoving){
			hero.updateFrame();
		}
		
	}
}

function Fireball (x, y, direction, id){
	this.x = x;
	this.y = y;
	this.id = id;
	this.w = 64;
	this.h = 64;
	this.speed = 8;
	this.frame = 0;
	this.direction = direction;
	
}
Fireball.prototype.draw = function(){
	//context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
	canvas.ctx.drawImage(sprites.fireball.image, 0+Math.floor(this.frame)*this.w, 0+this.direction*this.h, this.w, this.h, this.x, this.y, this.w/1.5, this.h/1.5);
}

Fireball.prototype.update = function(){
	if (this.direction === 0) { 
		this.y -= hero.speed;
	}
	if (this.direction === 2) { 
		this.y += this.speed;
	}
	if (this.direction === 1) { // Player holding left
		this.x -= this.speed;
	}
	if (this.direction === 3) { // Player holding right
		this.x += this.speed;
	}
	if (this.x > canvas.width || this.x < 0 - this.w || this.y > canvas.height || this.y < 0 - this.h){
		delete hero.casts[this.id];
	}
	this.updateFrame();
}
Fireball.prototype.updateFrame = function(){
	if(this.frame >= sprites.fireball.numberOfFrames){
		this.frame = 0;
	}else{
		this.frame += 1;
	}
}

function Armor(sprite){
	this.sprite = sprite;
}
//var test = new Fireball(20,35, 3);
document.addEventListener('keydown', function(e){
	keysDown[e.keyCode] = true;
}, false);

document.addEventListener('keyup', function(e){
	delete keysDown[e.keyCode];
}, false);

var map = {
	isChanging: false,
	changeStep: 0,
	position: [0,0],
	nextMap: 0,
	sprite: sprites.map00,
	update: function(){
		if(!map.isChanging){
			return;
		}
		var steps = 40;
		if (++map.changeStep >=  steps){
			map.isChanging = false;
			map.changeStep = 0;
			map.sprite = map.nextMap;
		}
	},
	draw: function (){
		//context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
		if(map.isChanging){
			map.change(map.changeStep, hero.direction);
			return;
		}
		canvas.ctx.drawImage(map.sprite.image,0,0);
	},
	change: function(step, direction){	
		var pace;
		var factor = [[0,-1],[-1,0],[0,1],[1,0]];
		switch (direction){
			case 0:
				pace = canvas.height/40;
				break
			case 1:
				pace = canvas.width/40;
				break;
			case 2:
				pace = canvas.height/40;
				break;
			case 3:
				pace = canvas.width/40;
				break;
		}
		//factor
		if(step > 2){
			hero.x -= pace*factor[direction][0];
			hero.y -= pace*factor[direction][1];
		}
		canvas.ctx.drawImage(map.sprite.image,(0 - step*pace)*factor[direction][0], (0 - step*pace)*factor[direction][1]);
		canvas.ctx.drawImage(map.nextMap.image,(canvas.width - step*pace)*factor[direction][0], (canvas.height - step*pace)*factor[direction][1]);

	},
	isClear: function(x, y, direction){
		switch(direction){
			case 0:			//up
				if (y <= 0){
					if (map.position[0] === 0){
						return false;
					}
					map.position[0] -= 1;
					startMapChanging();
				}
				return true;
			case 1:
				if (x <= 0){
					if (map.position[1] === 0){
						return false;
					}
					map.position[1] -= 1;
					startMapChanging();
				}
				return true;
			case 2:
				if (y > canvas.height - hero.h){
					if (map.position[0] === 1){
						return false;
					}
					map.position[0] += 1;
					startMapChanging();
				}
				return true;
			case 3:
				if (x >= canvas.width - hero.w){
					if (map.position[1] === 2){
						return false;
					}
					map.position[1] += 1;
					startMapChanging();
				}
				
				return true;
		}
		
		function startMapChanging(){
			map.nextMap = sprites['map' + map.position.join('')];
			map.isChanging = true;
			map.changeStep = 0;
		}
	}
}
var miniMap = {
	
}

var monster = new Monster(sprites.monster1Walk,sprites.monster1Hit);
function main(){
	canvas.ctx.clearRect(0,0,canvas.width,canvas.height);
	map.update();
	map.draw();
	var casts = Object.keys(hero.casts);
	
	for (var i = 0; i < casts.length; i++){	
		hero.casts[casts[i]].draw();
		hero.casts[casts[i]].update();
	}
	//if(!map.isChanging)
	hero.update();
	hero.draw();
	monster.update();
	monster.draw();
	//console.log(hero.casts);
	//console.log(hero.numOfCasts);
	
}
setInterval(main, 50)